package com.nx.platform.es.biz.esspider.handler;

import com.google.common.primitives.Ints;
import com.nx.platform.es.biz.esspider.entity.Item;
import com.nx.platform.es.common.utils.ComplexParser;
import com.nx.platform.es.common.utils.MoreMaps;
import com.nx.platform.es.common.utils.MoreSplitters;
import com.nx.platform.es.common.utils.Utils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author
 * @since 2017年3月27日
 */
@HandlerDefine(HandlerType.SIMPLE)
public class SimpleInfoParamsServicesConvertHandler extends AbstractSimpleHandler {

    private static final Logger LOGGER = LogManager.getLogger(SimpleInfoParamsServicesConvertHandler.class);
    private Set<String> longTypeParamIds;

    @Override
    public void init(Map<?, ?> settings) throws Exception {
        longTypeParamIds = MoreMaps.getStringSet(settings, "longTypeParamIds", MoreSplitters.COMMA);
    }

    @Override
    public void handle(Map<Long, Item> items) throws Exception {
        items.values().forEach((Item item) -> {
            Map<String, Object> doc = item.getDoc();
            Object oriParams = doc.remove("params");
            Object oriServices = doc.remove("services");
            Map<String, List<Long>> params = convertParams(oriParams);
            Set<Long> services = convertServices(oriServices);
            if (params != null) {
                doc.put("params", params);
                doc.put("param", mergeParams(params));
                doc.put("paramlong", mergeLongParams(params));
            }
            if (services != null) {
                doc.put("services", services);
            }
        });
    }

    private List<Long> mergeParams(Map<String, List<Long>> params) {
        return params.entrySet().stream().flatMap(e -> {
            Integer key = Ints.tryParse(e.getKey());
            if (key == null) {
                return Stream.empty();
            }
            // merge只支持Integer
            return e.getValue().stream().filter(v -> v <= Integer.MAX_VALUE).map(v -> Utils.merge(key, v.intValue()));
        }).collect(Collectors.toList());
    }

    private List<String> mergeLongParams(Map<String, List<Long>> params) {
        if (CollectionUtils.isEmpty(longTypeParamIds)) {
            return Collections.emptyList();
        }
        return params.entrySet().stream().filter(entry -> longTypeParamIds.contains(entry.getKey())).flatMap(e -> {
            Integer key = Ints.tryParse(e.getKey());
            if (key == null) {
                return Stream.empty();
            }
            // 针对long型数据处理
            return e.getValue().stream().map(v -> Utils.merge(key, v));
        }).collect(Collectors.toList());
    }

    private Map<String, List<Long>> convertParams(Object object) {
        if (object instanceof String) {
            try {
                return (Map<String, List<Long>>) ComplexParser.PARAM.parse(String.valueOf(object));
            } catch (Throwable e) {
                LOGGER.warn("convert params error: {}", object, e);
            }
        }
        return new LinkedHashMap<>(0);
    }

    private Set<Long> convertServices(Object object) {
        if (object instanceof String) {
            try {
                return (Set<Long>) ComplexParser.SERVICES.parse(String.valueOf(object));
            } catch (Throwable e) {
                LOGGER.warn("convert services error: {}", object, e);
            }
        }
        return new HashSet<>(0);
    }

}
